<?php
/**
 * Loger类提供基本的日志服务
 *
 * Here is an inline example:
 * <code>
 * <?php
 * if(!defined( 'DOCUROOT')){define( 'DOCUROOT',dirname(__FILE__));}
 * include( "./class.Loger.php" );
 * $log = new Loger();
 * $log->setLogFileName( DOCUROOT."/logx.txt" );
 * $log->setLogType( Loger::OUT_FILE );
 * $log->appendLog( "aaaa",1 );
 * ? >
 * </code>
 *
 * @copyright Copyright (c) 2006 Itin Studio(http://wanweiqun.blog.163.com)
 * @link http://wanweiqun.blog.163.com
 * @author kokko<kokko313@gmail.com>
 * @package com
 * @subpackage eefocus
 * @version class.Loger.php 1.0 2006-10-25 11:21
 */

class Loger{
	/**
     * 保存运行期间的日志，在脚本结束时将日志内容写入到文件
     *
     * @var string
	 * @access protected
     */
    protected $_log = '';

	/**
	 * 日志输出的形式 文件输出
	 *
	 * @var string
	 * @access public
	 */
	const OUT_FILE = 'FILE';
	
	/**
	 * 日志输出的形式 直接输出到屏幕
	 *
	 * @var string
	 * @access public
	 */
	const OUT_SCREEN = 'SCREEN';

	/**
	 * 日志输出的形式 输出HTML到浏览器
	 *
	 * @var string
	 * @access public
	 */
	const OUT_HTML = 'HTML';

	/**
     * 指示哪些级别的错误要保存到日志中
	 *
	 * @var array
	 * @access protected
	 * @static
	 */
	protected static $_logErrorLevel = array( 1=>'notice', 2=>'debug', 3=>'warning', 4=>'error', 5=>'exception',6=>'log' );

    /**
     * 日期格式
     *
     * @var string
	 * @access protected
     */
    protected $_logDateFormat = 'Y-m-d H:i:s';

    /**
     * 保存日志的文件名,这里要制定文件名的绝对路径
     *
     * @var string
	 * @access protected
     */
    protected $_logFilename;
	
	/**
     * 指示当日志文件超过多少 KB 时，自动创建新的日志文件，单位是 KB
	 * 
	 * @var int
	 * @access protected
     */
	protected $_logFileMaxSize = 4096;

    /**
     * 当前日志输出形式
     *
     * @var boolean
	 * @access protected
     */
    protected $_logType = self::OUT_SCREEN;

	/**
     * 构造函数
     *
     * @return void
     */
	function __construct(){
		list($usec, $sec) = explode( " ", microtime() );

        $this->_log = sprintf( "Start Logging [%s %s]==============\n",
			date( $this->_logDateFormat, $sec ), $usec );
		
		if (isset($_SERVER['REQUEST_URI'])) {
			$this->_log .= sprintf("[%s] REQUEST_URI: %s\n",
				date($this->_logDateFormat), $_SERVER['REQUEST_URI'] );
        }else{
			$this->_log .= sprintf("[%s] PHP SCRIPT: %s\n",
				date($this->_logDateFormat), $_SERVER['SCRIPT_FILENAME'] );
		}

		// 注册脚本结束时要运行的方法，将缓存的日志内容写入文件
	    register_shutdown_function( array( &$this, 'writeLog' ) );
	}//end function

	/**
	 * 设置log文件大小
	 *
	 * @param int $size log文件大小（单位KB）
	 * @access public
	 */
	function setLogFileMaxSize( $size ){
		$this->_logFileMaxSize = $size;
	}//end function
	
	/**
	 * 设置log存储文件
	 *
	 * @param string $file log文件路径（绝对路径）
	 * @access public
	 */
	function setLogFilename( $file ){
		$path = dirname( $file );
		if( !is_dir( $path ) )
			Files::mkdirs( $path );
		$this->_logFilename = $file;
	}//end function

	/**
	 * 设置log输出类型
	 *
	 * @param string $type log日志输出类型
	 * @access public
	 */
	function setLogType( $type ){
		$this->_logType = $type;
	}//end function

	/**
     * 追加日志信息
     *
     * @param string $msg
     * @param int $level
	 * @access public
     */
    function appendLog( $msg,$level )
    {
		$errorLevel = &self::$_logErrorLevel;
        $level = strtolower( $level );
        if ( !isset( $errorLevel[$level] ) ) { return; }
        $msg = sprintf( "[%s] [%s] %s\n", date( $this->_logDateFormat ), $errorLevel[$level], $msg );
        $this->_log .= $msg;
    }//end function
	
	/**
     * 输出日志信息
	 *
	 * @access public
     */
	function writeLog(){
		switch( strtoupper( $this->_logType ) ){
			case self::OUT_SCREEN: //直接打出到屏幕
				echo $this->_log;
				break;
			case self::OUT_HTML: //打出到浏览器
				echo "<pre>";
				echo nl2br( $this->_log );
				echo "</pre>";
				break;
			case self::OUT_FILE: //记录到文件
				//如果文件存在记录文件大小
				if ( file_exists( $this->_logFilename ) ) {
					$filesize = filesize( $this->_logFilename );
				} else { //文件不存在
					$dir = dirname( $this->_logFilename );
					$dir = realpath( $dir );
					//文件目录不存在或者不可写
					if( !is_dir( $dir ) && !is_writable($dir) )
						$this->_logFilename = $_ENV["TEMP"].DIRECTORY_SEPARATOR.basename( $this->_logFilename );
					$filesize = 0;
				}
				$maxsize = $this->_logFileMaxSize;
				if ($maxsize >= 512) {
					$maxsize = $maxsize * 1024;
					if ( $filesize >= $maxsize ) {
						// 使用新的日志文件名
						$pathinfo = pathinfo($this->_logFilename);
						$newFilename = $pathinfo['dirname'] . DIRECTORY_SEPARATOR .
							basename($pathinfo['basename'], '.' . $pathinfo['extension']) .
							date('-Ymd-His') . '.' . $pathinfo['extension'];
							rename( $this->_logFilename, $newFilename );
					}
				}
				$fp = fopen($this->_logFilename, 'a');
				if (!$fp) { return; }
				flock( $fp, LOCK_EX );
				fwrite( $fp, str_replace("\r", '', $this->_log ) );
				flock($fp, LOCK_UN);
				fclose($fp);
				break;
		}//end switch
	}//end function
}
?>
